package com.ysstech.common.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BigDecimalUtil {

    private static Logger log = LoggerFactory.getLogger(DateUtil.class);
    public static final String BIG_NUM_FMT_COMMA = "#,###,###,###,###,###,##0.00";//千位分隔符 方便查看金额具体大小
    public static final String BIG_NUM_FMT = "##################0.00";//不带千位分隔符
    public static final int SCALE = 2;//默认保留位数
   /* ROUND_HALF_UP: 遇到.5的情况时往上近似,例: 1.5 ->;2
    ROUND_HALF_DOWN : 遇到.5的情况时往下近似,例: 1.5 ->;1*/

    /**
     * BigDecimal比较大小
     */
    public static int compareTo(BigDecimal b1, BigDecimal b2) throws Exception {
        int num = 0;
        try {
            if (b1 == null || b2 == null) {
                throw new Exception("传入数据为空！");
            } else {
                num = b1.compareTo(b2);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("数据大小比较失败，请稍后重试！");
        }
        return num;
    }

    /**
     * 两个数相加 不保留位数
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal add(BigDecimal b1, BigDecimal b2) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (b1 == null || b1 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.add(b2);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相加出错，请稍后重试");
        }
        return bigDecimal;
    }

    public static BigDecimal add(BigDecimal b1, BigDecimal b2, BigDecimal b3) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (b1 == null || b1 == null || null == b3) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.add(b2).add(b3);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相加出错，请稍后重试");
        }
        return bigDecimal;
    }

    /**
     * 两个数相加
     * 默认四舍五入
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal add(BigDecimal b1, BigDecimal b2, int scale) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (scale < 0) {
                throw new Exception("保留位数不能小于0！");
            }
            if (b1 == null || b1 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相加出错，请稍后重试");
        }
        return bigDecimal;
    }

    public static BigDecimal add(BigDecimal b1, BigDecimal b2, BigDecimal b3, int scale) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (scale < 0) {
                throw new Exception("保留位数不能小于0！");
            }
            if (b1 == null || b2 == null || null == b3) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.add(b2).add(b3).setScale(scale, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相加出错，请稍后重试");
        }
        return bigDecimal;
    }

    /**
     * 两个数相减 不保留位数
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal subtract(BigDecimal b1, BigDecimal b2) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (b1 == null || b2 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.subtract(b2);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相减出错，请稍后重试");
        }
        return bigDecimal;
    }
    /**
     * 两个数相减 不保留位数
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal subtract(BigDecimal b1, BigDecimal b2, BigDecimal b3) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (b1 == null || b2 == null || b3 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.subtract(b2).subtract(b3);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相减出错，请稍后重试");
        }
        return bigDecimal;
    }

    /**
     * 两个数相减
     * 默认四舍五入
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal subtract(BigDecimal b1, BigDecimal b2, int scale) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (scale < 0) {
                throw new Exception("保留位数不能小于0！");
            }
            if (b1 == null || b2 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相减出错，请稍后重试");
        }
        return bigDecimal;
    }


    /**
     * 两个数相乘  不保留位数
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal multiply(BigDecimal b1, BigDecimal b2) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (b1 == null || b2 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.multiply(b2);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相乘出错，请稍后重试");
        }
        return bigDecimal;
    }
    public static BigDecimal multiply(BigDecimal b1, BigDecimal b2, BigDecimal b3) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (b1 == null || b2 == null || b3 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.multiply(b2).multiply(b3);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相乘出错，请稍后重试");
        }
        return bigDecimal;
    }
    /**
     * 两个数相乘
     * 默认四舍五入
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal multiply(BigDecimal b1, BigDecimal b2, int scale) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (scale < 0) {
                throw new Exception("保留位数不能小于0！");
            }
            if (b1 == null || b2 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相乘出错，请稍后重试");
        }
        return bigDecimal;
    }

    /**
     * 两个数相除
     * 默认四舍五入
     * 除法必须保留小数位数
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal divide(BigDecimal b1, BigDecimal b2) throws Exception {
        return divide(b1, b2, 2);
    }

    /**
     * 两个数相减
     * 默认四舍五入
     *
     * @param b1
     * @param b2
     * @return
     */
    public static BigDecimal divide(BigDecimal b1, BigDecimal b2, int scale) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (scale < 0) {
                throw new Exception("保留位数不能小于0！");
            }
            if (b2 == BigDecimal.ZERO) {
                throw new Exception("被除数不能为0！");
            }
            if (b1 == null || b2 == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相除出错，请稍后重试");
        }
        return bigDecimal;
    }

    /**
     * 保留小数位
     * 默认四舍五入
     *
     * @param b
     * @param scale
     * @return
     */
    public static BigDecimal round(BigDecimal b, int scale) throws Exception {
        BigDecimal bigDecimal = BigDecimal.ZERO;
        try {
            if (scale < 0) {
                throw new Exception("保留位数不能小于0！");
            }
            BigDecimal one = new BigDecimal("1");
            if (b == null) {
                throw new Exception("传入数据为空！");
            } else {
                bigDecimal = b.divide(one, scale, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception ex) {
            log.error(ex.toString());
            throw new Exception("两个数相乘出错，请稍后重试");
        }
        return bigDecimal;
    }

    /**
     * 格式化金额
     * 千位分隔符 方便查看金额具体大小 BIG_NUM_FMT = "#,###,###,###,###,###,##0.00"
     * 精确两位小数 .99 -> 0.99
     * 1111111.985 -> 1,111,111.99
     *
     * @param v
     * @return
     */
    public static String formatNumber(String v) throws Exception {
        if (StringUtils.isNotBlank(v)) {
            String str = formatNumber(v, BIG_NUM_FMT_COMMA);
            return str;
        } else {
            throw new Exception("传入数据为空！");
        }
    }

    /**
     * 格式化金额
     *
     * @param v
     * @param pattern BigNum类中的常量 BIG_NUM_FMT_COMMA,BIG_NUM_FMT
     * @return
     */
    public static String formatNumber(String v, String pattern) {
        return new DecimalFormat(pattern).format(new BigDecimal(v));
    }
}
